home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 5 / CU Amiga Magazine's Super CD-ROM 05 (1996)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1996-12].iso / cucd / programming / aros / dev / intuition / intui_x11.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-12  |  22.6 KB  |  1,095 lines

  1. #include <X11/Xlib.h>
  2. #include <X11/Xutil.h>
  3. #include <X11/cursorfont.h>
  4. #include <X11/keysym.h>
  5.  
  6. #undef CurrentTime /* Defined by X.h */
  7. #define XCurrentTime 0L
  8.  
  9. #define DEBUG_FreeMem 1
  10.  
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <exec/memory.h>
  15. #include <dos/dos.h>
  16. #include <utility/tagitem.h>
  17. #include <clib/exec_protos.h>
  18. #include <clib/intuition_protos.h>
  19. #include <clib/graphics_protos.h>
  20. #include <clib/aros_protos.h>
  21. #include "intuition_intern.h"
  22.  
  23. static struct IntuitionBase * IntuiBase;
  24.  
  25. extern Display * sysDisplay;
  26. extern long sysCMap[];
  27. extern unsigned long sysPlaneMask;
  28. extern Cursor sysCursor;
  29.  
  30. Display * GetSysDisplay (void);
  31. int      GetSysScreen (void);
  32. extern void SetGC (struct RastPort * rp, GC gc);
  33. extern GC GetGC (struct RastPort * rp);
  34. extern void SetXWindow (struct RastPort * rp, int win);
  35.  
  36. extern int CalcKnobSize (struct Gadget * propGadget, long * knobleft,
  37.             long * knobtop, long * knobwidth, long * knobheight);
  38.  
  39. static int MyErrorHandler (Display *, XErrorEvent *);
  40. static int MySysErrorHandler (Display *);
  41.  
  42. #define DEBUG            0
  43. #define DEBUG_OpenWindow    0
  44. #define DEBUG_CloseWindow    0
  45. #define DEBUG_ProcessXEvents    0
  46.  
  47. #if DEBUG
  48. #   define D(x)     x
  49. #else
  50. #   define D(x)     /* eps */
  51. #endif
  52.  
  53. #if DEBUG_ProcessXEvents
  54. #   define Dipxe(x) x
  55. #else
  56. #   define Dipxe(x) /* eps */
  57. #endif
  58.  
  59. #if DEBUG_OpenWindow
  60. #   define Diow(x) x
  61. #else
  62. #   define Diow(x) /* eps */
  63. #endif
  64.  
  65. #if DEBUG_CloseWindow
  66. #   define Dicw(x) x
  67. #else
  68. #   define Dicw(x) /* eps */
  69. #endif
  70.  
  71. #define bug        kprintf
  72.  
  73. struct IntWindow
  74. {
  75.     struct Window iw_Window;
  76.     int       iw_XWindow;
  77.     Region      iw_Region;
  78. };
  79.  
  80. struct _keytable
  81. {
  82.     KeySym keysym;
  83.     WORD   amiga;
  84.     UWORD  amiga_qual;
  85.     char * normal,
  86.      * shifted;
  87.     ULONG  keycode;
  88. }
  89. keytable[] =
  90. {
  91.     {XK_Return,     0x44, 0,              "\012",   "\012", 0 },
  92.     {XK_Right,        0x4e, 0,              "\233C",  "\233 A", 0 },
  93.     {XK_Up,        0x4c, 0,              "\233A",  "\233T",0 },
  94.     {XK_Left,        0x4f, 0,              "\233D",  "\233 @",0 },
  95.     {XK_Down,        0x4d, 0,              "\233B",  "\233S",0 },
  96.     {XK_Help,        0x5f, 0,              "\233?~", "\233?~",0 },
  97.     {XK_KP_Enter,    0x43, IEQUALIFIER_NUMERICPAD, "\015",   "\015",0 },
  98.     {XK_KP_Separator,    0x3c, IEQUALIFIER_NUMERICPAD, ".",      ".",0 },
  99.     {XK_KP_Subtract,    0x4a, IEQUALIFIER_NUMERICPAD, "-",      "-",0 },
  100.     {XK_KP_Decimal,    0x3c, IEQUALIFIER_NUMERICPAD, ".",      ".",0 },
  101.     {XK_KP_0,        0x0f, IEQUALIFIER_NUMERICPAD, "0",      "0",0 },
  102.     {XK_KP_1,        0x1d, IEQUALIFIER_NUMERICPAD, "1",      "1",0 },
  103.     {XK_KP_2,        0x1e, IEQUALIFIER_NUMERICPAD, "2",      "2",0 },
  104.     {XK_KP_3,        0x1f, IEQUALIFIER_NUMERICPAD, "3",      "3",0 },
  105.     {XK_KP_4,        0x2d, IEQUALIFIER_NUMERICPAD, "4",      "4",0 },
  106.     {XK_KP_5,        0x2e, IEQUALIFIER_NUMERICPAD, "5",      "5",0 },
  107.     {XK_KP_6,        0x2f, IEQUALIFIER_NUMERICPAD, "6",      "6",0 },
  108.     {XK_KP_7,        0x3d, IEQUALIFIER_NUMERICPAD, "7",      "7",0 },
  109.     {XK_KP_8,        0x3e, IEQUALIFIER_NUMERICPAD, "8",      "8",0 },
  110.     {XK_KP_9,        0x3f, IEQUALIFIER_NUMERICPAD, "9",      "9",0 },
  111.     {XK_F1,        0x50, 0,              "\2330~", "\23310~",0 },
  112.     {XK_F2,        0x51, 0,              "\2331~", "\23311~",0 },
  113.     {XK_F3,        0x52, 0,              "\2332~", "\23312~",0 },
  114.     {XK_F4,        0x53, 0,              "\2333~", "\23313~",0 },
  115.     {XK_F5,        0x54, 0,              "\2334~", "\23314~",0 },
  116.     {XK_F6,        0x55, 0,              "\2335~", "\23315~",0 },
  117.     {XK_F7,        0x56, 0,              "\2336~", "\23316~",0 },
  118.     {XK_F8,        0x57, 0,              "\2337~", "\23317~",0 },
  119.     {XK_F9,        0x58, 0,              "\2338~", "\23318~",0 },
  120.     {XK_F10,        0x59, 0,              "\2339~", "\23319~",0 },
  121.     {0, -1, 0, },
  122. };
  123.  
  124. #define SHIFT    (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)
  125. #define LALT    IEQUALIFIER_LALT
  126. #define RALT    IEQUALIFIER_RALT
  127. #define CTRL    IEQUALIFIER_CONTROL
  128. #define CAPS    IEQUALIFIER_CAPSLOCK
  129.  
  130.  
  131. static int MyErrorHandler (Display * display, XErrorEvent * errevent)
  132. {
  133.     char buffer[256];
  134.  
  135.     XGetErrorText (display, errevent->error_code, buffer, sizeof (buffer));
  136.  
  137.     fprintf (stderr
  138.     , "XError %d (Major=%d, Minor=%d)\n%s\n"
  139.     , errevent->error_code
  140.     , errevent->request_code
  141.     , errevent->minor_code
  142.     , buffer
  143.     );
  144.     fflush (stderr);
  145.  
  146.     exit (10);
  147. }
  148.  
  149. static int MySysErrorHandler (Display * display)
  150. {
  151.     perror ("X11-Error");
  152.     fflush (stderr);
  153.  
  154.     exit (10);
  155. }
  156.  
  157. int intui_init (struct IntuitionBase * IntuitionBase)
  158. {
  159.     int t;
  160.  
  161.     IntuitionBase->ActiveScreen->Width =
  162.     DisplayWidth (GetSysDisplay (), GetSysScreen ());
  163.     IntuitionBase->ActiveScreen->Height =
  164.     DisplayHeight (GetSysDisplay (), GetSysScreen ());
  165.  
  166.     for (t=0; keytable[t].amiga != -1; t++)
  167.     keytable[t].keycode = XKeysymToKeycode (sysDisplay,
  168.         keytable[t].keysym);
  169.  
  170.     XSetErrorHandler (MyErrorHandler);
  171.     XSetIOErrorHandler (MySysErrorHandler);
  172.  
  173.     IntuiBase = IntuitionBase;
  174.  
  175.     return True;
  176. }
  177.  
  178. int intui_open (struct IntuitionBase * IntuitionBase)
  179. {
  180.     return True;
  181. }
  182.  
  183. void intui_close (struct IntuitionBase * IntuitionBase)
  184. {
  185.     return;
  186. }
  187.  
  188. void intui_expunge (struct IntuitionBase * IntuitionBase)
  189. {
  190.     return;
  191. }
  192.  
  193. void intui_SetWindowTitles (struct Window * win, char * text, char * screen)
  194. {
  195.     XSizeHints hints;
  196.     struct IntWindow * w;
  197.  
  198.     w = (struct IntWindow *)win;
  199.  
  200.     hints.x     = win->LeftEdge;
  201.     hints.y     = win->TopEdge;
  202.     hints.width  = win->Width;
  203.     hints.height = win->Height;
  204.     hints.flags  = PPosition | PSize;
  205.  
  206.     if (screen == (char *)~0L)
  207.     screen = "Workbench 3.1";
  208.     else if (!screen)
  209.     screen = "";
  210.  
  211.     if (text == (char *)~0LL)
  212.     text = win->Title;
  213.     else if (!text)
  214.     text = "";
  215.  
  216.     XSetStandardProperties (sysDisplay, w->iw_XWindow, text, screen,
  217.         None, NULL, 0, &hints);
  218. }
  219.  
  220. int intui_GetWindowSize (void)
  221. {
  222.     return sizeof (struct IntWindow);
  223. }
  224.  
  225. int intui_OpenWindow (struct IntWindow * iw,
  226.     struct IntuitionBase * IntuitionBase)
  227. {
  228.     XGCValues gcval;
  229.     GC gc;
  230.  
  231.     iw->iw_XWindow = XCreateSimpleWindow (GetSysDisplay ()
  232.     , DefaultRootWindow (GetSysDisplay ())
  233.     , iw->iw_Window.LeftEdge
  234.     , iw->iw_Window.TopEdge
  235.     , iw->iw_Window.Width
  236.     , iw->iw_Window.Height
  237.     , 15
  238.     , sysCMap[1]
  239.     , sysCMap[0]
  240.     );
  241.  
  242.     SetXWindow (iw->iw_Window.RPort, iw->iw_XWindow);
  243.  
  244.     XSetGraphicsExposures (sysDisplay, gc, TRUE);
  245.  
  246.     /*TODO __SetSizeHints (w); */
  247.  
  248.     gcval.plane_mask = sysPlaneMask;
  249.  
  250.     gc = XCreateGC (sysDisplay, iw->iw_XWindow, GCPlaneMask, &gcval);
  251.  
  252.     if (!gc)
  253.     {
  254.     XDestroyWindow (sysDisplay, iw->iw_XWindow);
  255.     return FALSE;
  256.     }
  257.  
  258.     SetGC (iw->iw_Window.RPort, gc);
  259.  
  260.     iw->iw_Region = XCreateRegion ();
  261.  
  262.     if (!iw->iw_Region)
  263.     {
  264.     XDestroyWindow (sysDisplay, iw->iw_XWindow);
  265.     XFreeGC (sysDisplay, gc);
  266.     return FALSE;
  267.     }
  268.  
  269.     XSelectInput (sysDisplay
  270.     , iw->iw_XWindow
  271.     , ExposureMask
  272.         | ButtonPressMask
  273.         | ButtonReleaseMask
  274.         | PointerMotionMask
  275.         | KeyPressMask
  276.         | KeyReleaseMask
  277.         | EnterWindowMask
  278.         | LeaveWindowMask
  279.         | StructureNotifyMask
  280.     );
  281.  
  282.     XDefineCursor (sysDisplay, iw->iw_XWindow, sysCursor);
  283.     XMapRaised (sysDisplay, iw->iw_XWindow);
  284.  
  285.     XSync (sysDisplay, FALSE);
  286.  
  287.     Diow(bug("Opening Window %08lx (X=%ld)\n", w, iw->iw_XWindow));
  288.  
  289.     return 1;
  290. }
  291.  
  292. void intui_CloseWindow (struct IntWindow * iw,
  293.         struct IntuitionBase * IntuitionBase)
  294. {
  295.     Dicw(bug("Closing Window %08lx (X=%ld)\n", iw, iw->iw_XWindow));
  296.  
  297.     XDestroyWindow (sysDisplay, iw->iw_XWindow);
  298.  
  299.     XDestroyRegion (iw->iw_Region);
  300.  
  301.     XFreeGC (sysDisplay, GetGC(iw->iw_Window.RPort));
  302.  
  303.     XSync (sysDisplay, FALSE);
  304. }
  305.  
  306. void intui_WindowToFront (struct IntWindow * window)
  307. {
  308.     XRaiseWindow (sysDisplay, window->iw_XWindow);
  309. }
  310.  
  311. long StateToQualifier (unsigned long state)
  312. {
  313.     long result;
  314.  
  315.     result = 0;
  316.  
  317.     if (state & ShiftMask)
  318.     result |= SHIFT;
  319.  
  320.     if (state & ControlMask)
  321.     result |= CTRL;
  322.  
  323.     if (state & LockMask)
  324.     result |= CAPS;
  325.  
  326.     if (state & Mod2Mask) /* Right Alt */
  327.     result |= LALT;
  328.  
  329.     if (state & 0x2000) /* Mode switch */
  330.     result |= RALT;
  331.  
  332.     if (state & Mod1Mask) /* Left Alt */
  333.     result |= AMIGAKEYS;
  334.  
  335.     if (state & Button1Mask)
  336.     result |= IEQUALIFIER_LEFTBUTTON;
  337.  
  338.     if (state & Button2Mask)
  339.     result |= IEQUALIFIER_RBUTTON;
  340.  
  341.     if (state & Button3Mask)
  342.     result |= IEQUALIFIER_MIDBUTTON;
  343.  
  344.     return (result);
  345. }
  346.  
  347. long XKeyToAmigaCode (XKeyEvent * xk)
  348. {
  349.     char buffer[10];
  350.     KeySym ks;
  351.     int count;
  352.     long result;
  353.     short t;
  354.  
  355.     result = StateToQualifier (xk->state) << 16L;
  356.  
  357.     xk->state = 0;
  358.     count = XLookupString (xk, buffer, 10, &ks, NULL);
  359.  
  360.     for (t=0; keytable[t].amiga != -1; t++)
  361.     {
  362.     if (ks == keytable[t].keycode)
  363.     {
  364.         result |= (keytable[t].amiga_qual << 16) | keytable[t].amiga;
  365.         return (result);
  366.     }
  367.     }
  368.  
  369.     result |= xk->keycode & 0xffff;
  370.  
  371.     return (result);
  372. }
  373.  
  374. void intui_SizeWindow (struct Window * win, long dx, long dy)
  375. {
  376.     XResizeWindow (sysDisplay
  377.     , ((struct IntWindow *)win)->iw_XWindow
  378.     , win->Width + dx
  379.     , win->Height + dy
  380.     );
  381. }
  382.  
  383. void intui_ActivateWindow (struct IntWindow * win)
  384. {
  385.     XSetInputFocus (sysDisplay, win->iw_XWindow, RevertToNone, XCurrentTime);
  386. }
  387.  
  388. LONG intui_RawKeyConvert (struct InputEvent * ie, STRPTR buf,
  389.     LONG size, struct KeyMap * km)
  390. {
  391.     XKeyEvent xk;
  392.     char * ptr;
  393.     int t;
  394.  
  395.     ie->ie_Code &= 0x7fff;
  396.  
  397.     for (t=0; keytable[t].amiga != -1; t++)
  398.     {
  399.     if (ie->ie_Code == keytable[t].keycode)
  400.     {
  401.         if (ie->ie_Qualifier & SHIFT)
  402.         ptr = keytable[t].shifted;
  403.         else
  404.         ptr = keytable[t].normal;
  405.  
  406.         t = strlen(ptr);
  407.         if (t > size)
  408.         t = size;
  409.  
  410.         strncpy (buf, ptr, t);
  411.  
  412.         goto ende;
  413.     }
  414.     }
  415.  
  416.     xk.keycode = ie->ie_Code;
  417.     xk.display = sysDisplay;
  418.     xk.state = 0;
  419.  
  420.     if (ie->ie_Qualifier & SHIFT)
  421.     xk.state |= ShiftMask;
  422.  
  423.     if (ie->ie_Qualifier & CTRL)
  424.     xk.state |= ControlMask;
  425.  
  426.     if (ie->ie_Qualifier & CAPS)
  427.     xk.state |= LockMask;
  428.  
  429.     if (ie->ie_Qualifier & RALT)
  430.     xk.state |= 0x2000;
  431.  
  432.     if (ie->ie_Qualifier & LALT)
  433.     xk.state |= Mod2Mask;
  434.  
  435.     if (ie->ie_Qualifier & AMIGAKEYS)
  436.     xk.state |= Mod1Mask;
  437.  
  438.     if (ie->ie_Qualifier & IEQUALIFIER_LEFTBUTTON)
  439.     xk.state |= Button1Mask;
  440.  
  441.     if (ie->ie_Qualifier & IEQUALIFIER_MIDBUTTON)
  442.     xk.state |= Button2Mask;
  443.  
  444.     if (ie->ie_Qualifier & IEQUALIFIER_RBUTTON)
  445.     xk.state |= Button3Mask;
  446.  
  447.     t = XLookupString (&xk, buf, size, NULL, NULL);
  448.  
  449.     if (!*buf && t == 1) t = 0;
  450.     if (!t) *buf = 0;
  451.  
  452. ende:    /*printf ("RawKeyConvert: In %02x %04x %04x Out : %d cs %02x '%c'\n",
  453.         ie->ie_Code, ie->ie_Qualifier, xk.state, t, (ubyte)*buf,
  454.         (ubyte)*buf);*/
  455.  
  456.     return (t);
  457. }
  458.  
  459.  
  460. #ifdef TODO
  461. void RefreshWindowFrame (w)
  462. WIN * w;
  463. {
  464.     __SetSizeHints (w);
  465. }
  466.  
  467. int IntuiTextLength (itext)
  468. struct IntuiText * itext;
  469. {
  470.     return (100);
  471. }
  472.  
  473. void ClearMenuStrip (win)
  474. WIN * win;
  475. {
  476.     return;
  477. }
  478.  
  479. void BeginRefresh (win)
  480. WIN * win;
  481. {
  482.    /* Region aufpropfen */
  483.    XSetRegion (sysDisplay, win->RPort->gc, win->region);
  484. }
  485.  
  486.  
  487. void EndRefresh (win, free)
  488. WIN * win;
  489. BOOL free;
  490. {
  491.    Region region;
  492.    XRectangle rect;
  493.  
  494.    /* Zuerst alte Region freigeben (Speicher sparen) */
  495.    if (free)
  496.    {
  497.       XDestroyRegion (win->region);
  498.  
  499.       win->region = XCreateRegion ();
  500.    }
  501.  
  502.    /* Dann loeschen wir das ClipRect wieder indem wir ein neues
  503.       erzeugen, welches das ganze Fenster ueberdeckt. */
  504.    region = XCreateRegion ();
  505.  
  506.    rect.x      = 0;
  507.    rect.y      = 0;
  508.    rect.width  = win->Width;
  509.    rect.height = win->Height;
  510.  
  511.    XUnionRectWithRegion (&rect, region, region);
  512.  
  513.    /* und setzen */
  514.    XSetRegion (sysDisplay, win->RPort->gc, region);
  515. }
  516.  
  517. int AutoRequest (win, body, pos, neg, f_pos, f_neg, width, height)
  518. WIN * win;
  519. struct IntuiText * body, * pos, * neg;
  520. ULONG f_pos, f_neg;
  521. SHORT width, height;
  522. {
  523.     return (TRUE);
  524. }
  525.  
  526. void GetScreenData (scr, size, type, screen)
  527. struct Screen * scr, * screen;
  528. long size, type;
  529. {
  530.     if (type != WBENCHSCREEN)
  531.     {
  532.     movmem (scr, screen, size);
  533.     }
  534.     else
  535.     {
  536.     WB.Width = DisplayWidth(sysDisplay, sys_screen);
  537.     WB.Height = DisplayHeight (sysDisplay, sys_screen);
  538.     movmem (scr, &WB, size);
  539.     }
  540. }
  541.  
  542. #endif
  543.  
  544. #define ADDREL(gad,flag,w,field) ((gad->Flags & (flag)) ? w->field : 0)
  545. #define GetLeft(gad,w)           (ADDREL(gad,GFLG_RELRIGHT,w,Width)   + gad->LeftEdge)
  546. #define GetTop(gad,w)            (ADDREL(gad,GFLG_RELBOTTOM,w,Height) + gad->TopEdge)
  547. #define GetWidth(gad,w)          (ADDREL(gad,GFLG_RELWIDTH,w,Width)   + gad->Width)
  548. #define GetHeight(gad,w)         (ADDREL(gad,GFLG_RELHEIGHT,w,Height) + gad->Height)
  549.  
  550. #define InsideGadget(w,gad,x,y)   \
  551.         ((x) >= GetLeft(gad,w) && (y) >= GetTop(gad,w) \
  552.         && (x) < GetLeft(gad,w) + GetWidth(gad,w) \
  553.         && (y) < GetTop(gad,w) + GetHeight(gad,w))
  554.  
  555.  
  556. struct Gadget * FindGadget (struct Window * window, int x, int y)
  557. {
  558.     struct Gadget * gadget;
  559.     int gx, gy;
  560.  
  561.     for (gadget=window->FirstGadget; gadget; gadget=gadget->NextGadget)
  562.     {
  563.     gx = x - GetLeft(gadget,window);
  564.     gy = y - GetTop(gadget,window);
  565.  
  566.     if (gx >= 0
  567.         && gy >= 0
  568.         && gx < GetWidth(gadget,window)
  569.         && gy < GetHeight(gadget,window)
  570.     )
  571.         break;
  572.     }
  573.  
  574.     return gadget;
  575. } /* FindGadget */
  576.  
  577. /* Use local copy of IntuitionBase */
  578. #define IntuitionBase IntuiBase
  579.  
  580. void intui_ProcessEvents (void)
  581. {
  582.     struct IntuiMessage * im;
  583.     struct Window    * w;
  584.     struct IntWindow    * iw;
  585.     struct Gadget    * gadget;
  586.     struct MsgPort    * intuiReplyPort;
  587.     struct Screen    * screen;
  588.     char * ptr;
  589.     int    mpos_x, mpos_y;
  590.     int    wait;
  591.     XEvent event;
  592.  
  593.     intuiReplyPort = CreateMsgPort ();
  594.     wait = 0;
  595.  
  596.     for (;;)
  597.     {
  598.     im = NULL;
  599.     w = NULL;
  600.  
  601.     while (XPending (sysDisplay))
  602.     {
  603.         XNextEvent (sysDisplay, &event);
  604.  
  605.         Dipxe(bug("Got Event for X=%d\n", event.xany.window));
  606.  
  607.         if (event.type == MappingNotify)
  608.         {
  609.         XRefreshKeyboardMapping ((XMappingEvent*)&event);
  610.         continue;
  611.         }
  612.  
  613.         /* Search window */
  614.         for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen)
  615.         {
  616.         for (w=screen->FirstWindow; w; w=w->NextWindow)
  617.         {
  618.             if (((struct IntWindow *)w)->iw_XWindow == event.xany.window)
  619.             break;
  620.         }
  621.         }
  622.  
  623.         if (w)
  624.         {
  625.         Dipxe(bug("X=%d is asocciated with Window %08lx\n",
  626.             event.xany.window,
  627.             (ULONG)w));
  628.         }
  629.         else
  630.         Dipxe(bug("X=%d is not asocciated with a Window\n",
  631.             event.xany.window));
  632.  
  633.         if (!w)
  634.         continue;
  635.  
  636.         iw = (struct IntWindow *)w;
  637.  
  638.         if (!im)
  639.         im = AllocMem (sizeof (struct IntuiMessage), MEMF_CLEAR);
  640.  
  641.         im->Class        = 0L;
  642.         im->IDCMPWindow = w;
  643.         im->MouseX        = mpos_x;
  644.         im->MouseY        = mpos_y;
  645.  
  646.         switch (event.type)
  647.         {
  648.         case GraphicsExpose:
  649.         case Expose: {
  650.         XRectangle rect;
  651.         UWORD       count;
  652.  
  653.         if (event.type == Expose)
  654.         {
  655.             rect.x    = event.xexpose.x;
  656.             rect.y    = event.xexpose.y;
  657.             rect.width    = event.xexpose.width;
  658.             rect.height = event.xexpose.height;
  659.             count    = event.xexpose.count;
  660.         }
  661.         else
  662.         {
  663.             rect.x    = event.xgraphicsexpose.x;
  664.             rect.y    = event.xgraphicsexpose.y;
  665.             rect.width    = event.xgraphicsexpose.width;
  666.             rect.height = event.xgraphicsexpose.height;
  667.             count    = event.xgraphicsexpose.count;
  668.         }
  669.  
  670.         XUnionRectWithRegion (&rect, iw->iw_Region, iw->iw_Region);
  671.  
  672.         if (count != 0)
  673.             break;
  674.  
  675.         RefreshGadgets (w->FirstGadget, w, NULL);
  676.  
  677.         im->Class = IDCMP_REFRESHWINDOW;
  678.         ptr      = "REFRESHWINDOW";
  679.         } break;
  680.  
  681.         case ConfigureNotify:
  682.         if (w->Width != event.xconfigure.width ||
  683.             w->Height != event.xconfigure.height)
  684.         {
  685.             w->Width  = event.xconfigure.width;
  686.             w->Height = event.xconfigure.height;
  687.  
  688.             im->Class = NEWSIZE;
  689.             ptr       = "NEWSIZE";
  690.         }
  691.  
  692.         break;
  693.  
  694.         case ButtonPress: {
  695.         XButtonEvent * xb = &event.xbutton;
  696.  
  697.         im->Class = MOUSEBUTTONS;
  698.         im->Qualifier = StateToQualifier (xb->state);
  699.         im->MouseX = xb->x;
  700.         im->MouseY = xb->y;
  701.  
  702.         switch (xb->button)
  703.         {
  704.         case Button1:
  705.             im->Code = SELECTDOWN;
  706.  
  707.             gadget = FindGadget (w, xb->x, xb->y);
  708.  
  709.             if (gadget)
  710.             {
  711.             if (gadget->Activation & GACT_IMMEDIATE)
  712.             {
  713.                 im->Class = GADGETDOWN;
  714.                 im->IAddress = gadget;
  715.                 ptr       = "GADGETDOWN";
  716.             }
  717.  
  718.             switch (gadget->GadgetType & GTYP_GTYPEMASK)
  719.             {
  720.             case GTYP_BOOLGADGET:
  721.                 if (gadget->Activation & GACT_TOGGLESELECT)
  722.                 gadget->Flags ^= GFLG_SELECTED;
  723.                 else
  724.                 gadget->Flags |= GFLG_SELECTED;
  725.  
  726.                 break;
  727.  
  728.             case GTYP_PROPGADGET: {
  729.                 long knobleft, knobtop, knobwidth, knobheight;
  730.                 struct PropInfo * pi;
  731.  
  732.                 pi = (struct PropInfo *)gadget->SpecialInfo;
  733.  
  734.                 if (!pi)
  735.                 break;
  736.  
  737.                 knobleft   = GetLeft (gadget, w);
  738.                 knobtop    = GetTop (gadget, w);
  739.                 knobwidth  = GetWidth (gadget, w);
  740.                 knobheight = GetHeight (gadget, w);
  741.  
  742.                 if (!CalcKnobSize (gadget
  743.                 , &knobleft, &knobtop, &knobwidth, &knobheight)
  744.                 )
  745.                 break;
  746.  
  747.                 if (pi->Flags & FREEHORIZ)
  748.                 {
  749.                 if (xb->x < knobleft)
  750.                 {
  751.                     if (pi->HorizPot > pi->HPotRes)
  752.                     pi->HorizPot -= pi->HPotRes;
  753.                     else
  754.                     pi->HorizPot = 0;
  755.                 }
  756.                 else if (xb->x >= knobleft + knobwidth)
  757.                 {
  758.                     if (pi->HorizPot + pi->HPotRes < MAXPOT)
  759.                     pi->HorizPot += pi->HPotRes;
  760.                     else
  761.                     pi->HorizPot = MAXPOT;
  762.                 }
  763.                 }
  764.  
  765.                 if (pi->Flags & FREEVERT)
  766.                 {
  767.                 if (xb->y < knobtop)
  768.                 {
  769.                     if (pi->VertPot > pi->VPotRes)
  770.                     pi->VertPot -= pi->VPotRes;
  771.                     else
  772.                     pi->VertPot = 0;
  773.                 }
  774.                 else if (xb->y >= knobtop + knobheight)
  775.                 {
  776.                     if (pi->VertPot + pi->VPotRes < MAXPOT)
  777.                     pi->VertPot += pi->VPotRes;
  778.                     else
  779.                     pi->VertPot = MAXPOT;
  780.                 }
  781.                 }
  782.  
  783.                 if (xb->x >= knobleft
  784.                 && xb->y >= knobtop
  785.                 && xb->x < knobleft + knobwidth
  786.                 && xb->y < knobtop + knobheight
  787.                 )
  788.                 pi->Flags |= KNOBHIT;
  789.                 else
  790.                 pi->Flags &= ~KNOBHIT;
  791.  
  792.                 gadget->Flags |= GFLG_SELECTED;
  793.  
  794.                 break; }
  795.             }
  796.  
  797.             RefreshGList (gadget, w, NULL, 1);
  798.             }
  799.  
  800.             break;
  801.  
  802.         case Button2:
  803.             im->Code = MIDDLEDOWN;
  804.             break;
  805.  
  806.         case Button3:
  807.             im->Code = MENUDOWN;
  808.             break;
  809.         }
  810.  
  811.         if (im->Class == MOUSEBUTTONS)
  812.             ptr = "MOUSEBUTTONS";
  813.         } break;
  814.  
  815.         case ButtonRelease: {
  816.         XButtonEvent * xb = &event.xbutton;
  817.  
  818.         im->Class = MOUSEBUTTONS;
  819.         im->Qualifier = StateToQualifier (xb->state);
  820.         im->MouseX = xb->x;
  821.         im->MouseY = xb->y;
  822.  
  823.         switch (xb->button)
  824.         {
  825.         case Button1:
  826.             im->Code = SELECTUP;
  827.  
  828.             if (gadget)
  829.             {
  830.             int inside = InsideGadget(w,gadget,xb->x,xb->y);
  831.             int selected = (gadget->Flags & GFLG_SELECTED) != 0;
  832.  
  833.             if (inside && (gadget->Activation & GACT_RELVERIFY))
  834.             {
  835.                 im->Class = GADGETUP;
  836.                 im->IAddress = gadget;
  837.                 ptr       = "GADGETDOWN";
  838.             }
  839.  
  840.             switch (gadget->GadgetType & GTYP_GTYPEMASK)
  841.             {
  842.             case GTYP_BOOLGADGET:
  843.                 if (!(gadget->Activation & GACT_TOGGLESELECT) )
  844.                 gadget->Flags &= ~GFLG_SELECTED;
  845.  
  846.                 if (selected)
  847.                 RefreshGList (gadget, w, NULL, 1);
  848.  
  849.                 break;
  850.  
  851.             case GTYP_PROPGADGET: {
  852.                 struct PropInfo * pi;
  853.  
  854.                 pi = (struct PropInfo *)gadget->SpecialInfo;
  855.  
  856.                 if (pi)
  857.                 pi->Flags &= ~KNOBHIT;
  858.  
  859.                 gadget->Flags &= ~GFLG_SELECTED;
  860.  
  861.                 RefreshGList (gadget, w, NULL, 1);
  862.  
  863.                 break; }
  864.  
  865.             }
  866.  
  867.             gadget = NULL;
  868.             }
  869.  
  870.             break;
  871.  
  872.         case Button2:
  873.             im->Code = MIDDLEUP;
  874.             break;
  875.  
  876.         case Button3:
  877.             im->Code = MENUUP;
  878.             break;
  879.         }
  880.  
  881.         ptr = "MOUSEBUTTONS";
  882.         } break;
  883.  
  884.         case KeyPress: {
  885.         XKeyEvent * xk = &event.xkey;
  886.         ULONG result;
  887.  
  888.         im->Class = RAWKEY;
  889.         result = XKeyToAmigaCode(xk);
  890.         im->Code = xk->keycode;
  891.         im->Qualifier = result >> 16;
  892.  
  893.         ptr = NULL;
  894.         } break;
  895.  
  896.         case KeyRelease: {
  897.         XKeyEvent * xk = &event.xkey;
  898.         ULONG result;
  899.  
  900.         im->Class = RAWKEY;
  901.         result = XKeyToAmigaCode(xk);
  902.         im->Code = xk->keycode | 0x8000;
  903.         im->Qualifier = result >> 16;
  904.  
  905.         ptr = NULL;
  906.         } break;
  907.  
  908.         case MotionNotify: {
  909.         XMotionEvent * xm = &event.xmotion;
  910.  
  911.         im->Code = IECODE_NOBUTTON;
  912.         im->Class = MOUSEMOVE;
  913.         im->Qualifier = StateToQualifier (xm->state);
  914.         im->MouseX = xm->x;
  915.         im->MouseY = xm->y;
  916.  
  917.         if (gadget)
  918.         {
  919.             int inside = InsideGadget(w,gadget,xm->x,xm->y);
  920.             int selected = (gadget->Flags & GFLG_SELECTED) != 0;
  921.  
  922.             switch (gadget->GadgetType & GTYP_GTYPEMASK)
  923.             {
  924.             case GTYP_BOOLGADGET:
  925.             if (inside != selected)
  926.             {
  927.                 gadget->Flags ^= GFLG_SELECTED;
  928.  
  929.                 RefreshGList (gadget, w, NULL, 1);
  930.             }
  931.  
  932.             break;
  933.  
  934.             case GTYP_PROPGADGET: {
  935.             long knobleft, knobtop, knobwidth, knobheight;
  936.             long dx, dy;
  937.             struct PropInfo * pi;
  938.  
  939.             pi = (struct PropInfo *)gadget->SpecialInfo;
  940.  
  941.             /* Has propinfo and the mouse was over the
  942.                 knob */
  943.             if (pi && (pi->Flags & KNOBHIT))
  944.             {
  945.                 knobleft   = GetLeft (gadget, w);
  946.                 knobtop    = GetTop (gadget, w);
  947.                 knobwidth  = GetWidth (gadget, w);
  948.                 knobheight = GetHeight (gadget, w);
  949.  
  950.                 if (!CalcKnobSize (gadget
  951.                 , &knobleft, &knobtop
  952.                 , &knobwidth, &knobheight)
  953.                 )
  954.                 break;
  955.  
  956.                 /* Delta movement */
  957.                 dx = xm->x - mpos_x;
  958.                 dy = xm->y - mpos_y;
  959.  
  960.                 /* Move the knob the same amount, ie.
  961.                 knobleft += dx; knobtop += dy;
  962.  
  963.                 knobleft = knobleft
  964.                     + (pi->CWidth - knobwidth)
  965.                     * pi->HorizPot / MAXPOT;
  966.  
  967.                 ie. dx = (pi->CWidth - knobwidth)
  968.                     * pi->HorizPot / MAXPOT;
  969.  
  970.                 or
  971.  
  972.                 pi->HorizPot = (dx * MAXPOT) /
  973.                     (pi->CWidth - knobwidth);
  974.                 */
  975.                 if (pi->Flags & FREEHORIZ
  976.                 && pi->CWidth != knobwidth)
  977.                 {
  978.                 dx = (dx * MAXPOT) /
  979.                     (pi->CWidth - knobwidth);
  980.  
  981.                 if (dx < 0)
  982.                 {
  983.                     dx = -dx;
  984.  
  985.                     if (dx > pi->HorizPot)
  986.                     pi->HorizPot = 0;
  987.                     else
  988.                     pi->HorizPot -= dx;
  989.                 }
  990.                 else
  991.                 {
  992.                     if (dx + pi->HorizPot > MAXPOT)
  993.                     pi->HorizPot = MAXPOT;
  994.                     else
  995.                     pi->HorizPot += dx;
  996.                 }
  997.                 } /* FREEHORIZ */
  998.  
  999.                 if (pi->Flags & FREEVERT
  1000.                 && pi->CHeight != knobheight)
  1001.                 {
  1002.                 dy = (dy * MAXPOT) /
  1003.                     (pi->CHeight - knobheight);
  1004.  
  1005.                 if (dy < 0)
  1006.                 {
  1007.                     dy = -dy;
  1008.  
  1009.                     if (dy > pi->VertPot)
  1010.                     pi->VertPot = 0;
  1011.                     else
  1012.                     pi->VertPot -= dy;
  1013.                 }
  1014.                 else
  1015.                 {
  1016.                     if (dy + pi->VertPot > MAXPOT)
  1017.                     pi->VertPot = MAXPOT;
  1018.                     else
  1019.                     pi->VertPot += dy;
  1020.                 }
  1021.                 } /* FREEVERT */
  1022.             } /* Has PropInfo and Mouse is over knob */
  1023.  
  1024.             RefreshGList (gadget, w, NULL, 1);
  1025.  
  1026.             break; } /* PROPGADGET */
  1027.  
  1028.             } /* switch GadgetType */
  1029.         } /* if (gadget) */
  1030.  
  1031.         ptr = "MOUSEMOVE";
  1032.         } break; /* MotioNotify */
  1033.  
  1034.         case EnterNotify: {
  1035.         XCrossingEvent * xc = &event.xcrossing;
  1036.  
  1037.         im->Class = ACTIVEWINDOW;
  1038.         im->MouseX = xc->x;
  1039.         im->MouseY = xc->y;
  1040.  
  1041.         ptr = "ACTIVEWINDOW";
  1042.         } break;
  1043.  
  1044.         case LeaveNotify: {
  1045.         XCrossingEvent * xc = &event.xcrossing;
  1046.  
  1047.         im->Class = ACTIVEWINDOW;
  1048.         im->MouseX = xc->x;
  1049.         im->MouseY = xc->y;
  1050.  
  1051.         ptr = "INACTIVEWINDOW";
  1052.         } break;
  1053.  
  1054.         default:
  1055.         ptr = NULL;
  1056.         break;
  1057.         } /* switch */
  1058.  
  1059.         mpos_x = im->MouseX;
  1060.         mpos_y = im->MouseY;
  1061.  
  1062.         if (ptr)
  1063.         Dipxe(bug("Msg=%s\n", ptr));
  1064.  
  1065.         if (im->Class)
  1066.         {
  1067.         if ((im->Class & w->IDCMPFlags) && w->UserPort)
  1068.         {
  1069.             im->ExecMessage.mn_ReplyPort = intuiReplyPort;
  1070.  
  1071.             PutMsg (w->UserPort, (struct Message *)im);
  1072.             im = NULL;
  1073.             wait ++;
  1074.         }
  1075.         else
  1076.             im->Class = 0;
  1077.         }
  1078.     }
  1079.  
  1080.     if (im)
  1081.         FreeMem (im, sizeof (struct IntuiMessage));
  1082.  
  1083.     Wait (1L << intuiReplyPort->mp_SigBit | SIGBREAKF_CTRL_F);
  1084.  
  1085.     /* Empty port */
  1086.     while ((im = (struct IntuiMessage *)GetMsg (intuiReplyPort)))
  1087.     {
  1088.         FreeMem (im, sizeof (struct IntuiMessage));
  1089.         wait --;
  1090.     }
  1091.     }
  1092. }
  1093.  
  1094.  
  1095.